package com.tbl.modules.wms.controller.allo;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.tbl.common.utils.DateUtils;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.constant.LogActionConstant;
import com.tbl.modules.platform.constant.MenuConstant;
import com.tbl.modules.platform.controller.AbstractController;
import com.tbl.modules.platform.service.system.LogService;
import com.tbl.modules.platform.service.system.RoleService;
import com.tbl.modules.platform.util.DeriveExcel;
import com.tbl.modules.wms.constant.EmumConstant;
import com.tbl.modules.wms.entity.allo.AllocationDetail;
import com.tbl.modules.wms.entity.baseinfo.*;
import com.tbl.modules.wms.entity.instorage.InstorageDetail;
import com.tbl.modules.wms.service.allo.AllocationDetailService;
import com.tbl.modules.wms.service.allo.AllocationService;
import com.tbl.modules.wms.service.baseinfo.*;
import com.tbl.modules.wms.service.instorage.InstorageDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 调拨管理--入库管理
 * @author 70486
 */
@Controller
@RequestMapping(value = "/allostoragein")
public class AlloStorageInController extends AbstractController {

    /**
     * 日志信息
     */
    @Autowired
    private LogService logService;
    /**
     * 调拨管理-调拨表
     */
    @Autowired
    private AllocationService allocationService;
    /**
     * 调拨管理-调拨详情
     */
    @Autowired
    private AllocationDetailService allocationDetailService;
    /**
     * 角色
     */
    @Autowired
    private RoleService roleService;
    /**
     * 库位信息
     */
    @Autowired
    private ShelfService shelfService;
    /**
     * 仓库
     */
    @Autowired
    private WarehouseService warehouseService;
    /**
     * 行车
     */
    @Autowired
    private CarService carService;
    /**
     * 盘具
     */
    @Autowired
    private DishService dishService;
    /**
     * 厂区服务类
     */
    @Autowired
    private FactoryAreaService factoryAreaService;
    /**
     * 标签表
     */
    @Autowired
    private InstorageDetailService instorageDetailService;
    
    /**
     * 跳转到调拨入库管理列表页面
     * @return ModelAndView
     */
    @RequestMapping(value = "/toList")
    public ModelAndView toList() {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("operationCode", roleService.selectOperationByRoleId(getSessionUser().getRoleId(), MenuConstant.allostoragein));
        mv.setViewName("techbloom/allo/alloinstorage/allostoragein_list");
        return mv;
    }

    /**
     * 获取调拨入库列表数据
     * @param queryJsonString
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/list.do")
    @ResponseBody
    public Map<String, Object> list(String queryJsonString) {
        Map<String, Object> map = new HashMap<>(4);
        if (!StringUtils.isEmptyString(queryJsonString)) {
            map = JSON.parseObject(queryJsonString);
        }
        PageTbl page = this.getPage();
        //okk
        map.put("org", Arrays.asList(getSessionUser().getFactoryCode().split(",")));
        PageUtils utils = allocationService.getInDetailList(page, map);
        page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        //初始化分页对象
        executePageMap(map, page);
        map.put("rows", utils.getList());
        map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        return map;
    }

    /**
     * 功能描述:  点击开始入库，选择仓库和行车
     * @param id 调拨明细表主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/storagestart.do")
    public ModelAndView storageStart(Long id) {
        ModelAndView mv = this.getModelAndView();
        mv.setViewName("techbloom/allo/alloinstorage/allostorage_start");
        AllocationDetail allocationDetail = allocationService.getDetailById(id);
        List<InstorageDetail> lstInstorageDetail = instorageDetailService.selectList(new EntityWrapper<InstorageDetail>()
                .eq("QACODE", allocationDetail.getQaCode()));
        InstorageDetail instorageDetail = null;
        if (lstInstorageDetail!=null && lstInstorageDetail.size()>0){
            instorageDetail = lstInstorageDetail.get(0);
        }
        List<Car> carList = allocationService.getCarList(allocationDetail.getWarehouseId());
        
        //获得初始化的推荐库位
        String recommendCode;
    	Warehouse warehouse = warehouseService.selectById(allocationDetail.getWarehouseId());
    	Dish dish = dishService.selectOne(new EntityWrapper<Dish>().eq("CODE", allocationDetail.getDishnumber()));
        
        List<Shelf> recommendShelfs = shelfService.selectRecommentList(warehouse.getFactoryCode(), warehouse.getCode(), dish.getOuterDiameter(),
                dish.getDrumType(), carList.get(0).getCode(),"", carList.size() > 0 ? carList.get(0).getWarehouseArea() : "",
                allocationDetail.getSalesCode(), dish.getSuperWide(), "黑色".equals(instorageDetail!=null?instorageDetail.getColour() : null)
                        ||StringUtils.isBlank(Objects.requireNonNull(instorageDetail).getColour()) ? 0 : 1);
        if(recommendShelfs.size()>0) {
        	recommendCode = recommendShelfs.get(0).getCode();
        }else {
        	//获取未被占用的库位
            List<Shelf> shelfCodeList = shelfService.getRecommendShelf(warehouse.getCode(),warehouse.getFactoryCode(),
                    carList.size()>0&&StringUtils.isNotBlank(carList.get(0).getWarehouseArea())?carList.get(0).getWarehouseArea():"");
        	recommendCode = shelfCodeList.size()>0?shelfCodeList.get(0).getCode():"";
        }
        
        mv.addObject("recommendCode",recommendCode);
        mv.addObject("allocationDetailId",id);
        mv.addObject("info", allocationDetail);
        mv.addObject("warehouseList", allocationService.getWarehouseList(allocationDetail.getOrg()));
        mv.addObject("carList", carList);
        return mv;
    }

    /**
     * 获得行车信息
     * @param id 仓库主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/warehouseChangeList.do")
    @ResponseBody
    public Map<String, Object> warehouseChangeList(Long id) {
        Map<String, Object> map = new HashMap<>(1);
        map.put("list", allocationService.getCarList(id));
        return map;
    }

    /**
     * 功能描述: 点击开始入库确认
     * 1.更新仓库，行车，状态信息
     * 2.判断当前状态 （1.未确认 2.已包装  3.入库中  4.入库完成）
     * @param allocationDetail 调拨单明细
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/updateWarehouseAndCar")
    @ResponseBody
    public Map<String, Object> updateWarehouseAndCar(AllocationDetail allocationDetail) {
        Map<String, Object> map = new HashMap<>(2);
        String msg;
        boolean result = false;
        Integer state = allocationDetailService.selectById(allocationDetail.getId()).getState();
        if (state.equals(EmumConstant.locationChangeStatus.START_CHANGE_IN.getCode())) {
            msg = "已经开始入库操作，请勿重复提交！";
        } else if (state.equals(EmumConstant.locationChangeStatus.COMPLETE_CHANGE_IN.getCode())) {
            msg = "入库完成,请勿重复提交！";
        } else {
            allocationService.updateDetail(allocationDetail);
            msg = "提交成功！";
            result = true;
        }
        map.put("result", result);
        map.put("msg", msg);
        return map;
    }

    /**
     * 点击入库确认，跳转页面
     * @param id 调拨单明细主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/storageconfirm.do")
    public ModelAndView storageConfirm(Long id) {
        ModelAndView mv = this.getModelAndView();
        AllocationDetail allocationDetail = allocationDetailService.selectById(id);
        String recommendCode;
        Dish dish = dishService.selectOne(new EntityWrapper<Dish>().eq("CODE", allocationDetail.getDishnumber()));
        Car car = carService.selectOne(new EntityWrapper<Car>().eq("CODE", allocationDetail.getInCarCode()));
        InstorageDetail instorageDetail = instorageDetailService.selectOne(new EntityWrapper<InstorageDetail>().eq("CODE", allocationDetail.getQaCode()));

    	 //获取未被占用的库位
        List<Shelf> recommendShelfs=shelfService.selectRecommentList(allocationDetail.getOrg(),allocationDetail.getInWarehouseCode(),dish.getOuterDiameter(),
                dish.getDrumType(),car.getCode(), "",car.getWarehouseArea(),allocationDetail.getSalesCode(),dish.getSuperWide(),
                "黑色".equals(instorageDetail.getColour())||StringUtils.isBlank(instorageDetail.getColour()) ? 0 : 1);
        if(recommendShelfs.size()>0) {
        	recommendCode = recommendShelfs.get(0).getCode();
        }else {
            List<Shelf> shelfCodeList = shelfService.getRecommendShelf(allocationDetail.getInWarehouseCode(),allocationDetail.getOrg(),car.getWarehouseArea());
        	recommendCode = shelfCodeList.size() > 0 ? shelfCodeList.get(0).getCode() : "";
        }
        mv.addObject("info", allocationService.getDetailById(id));
        mv.addObject("recommendCode", recommendCode);
        mv.setViewName("techbloom/allo/alloinstorage/allostorage_confirm");
        return mv;
    }

    /**
     * 手动入库，跳转页面
     * @param id 调拨单明细主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/storageManual.do")
    public ModelAndView storageManual(Long id) {
        ModelAndView mv = this.getModelAndView();
        AllocationDetail allocationDetail = allocationDetailService.selectById(id);

        mv.addObject("info", allocationService.getDetailById(id));
        mv.addObject("recommendCode", "");
        mv.addObject("info", allocationService.getDetailById(id));
        mv.addObject("warehouseList", allocationService.getWarehouseList(allocationDetail.getOrg()));
        mv.addObject("factory", factoryAreaService.selectOne(new EntityWrapper<FactoryArea>().eq("CODE",allocationDetail.getOrg())).getName());
        mv.setViewName("techbloom/allo/alloinstorage/allostorage_manual_in");
        return mv;
    }

    /**
     * 调拨入库-入库确认-选择库位
     * @param warehouseId 仓库主键
     * @param queryString
     * @param pageSize
     * @param pageNo
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/selectUnbindShelf.do")
    @ResponseBody
    public Map<String, Object> selectUnbindShelf(Long warehouseId,String queryString,int pageSize,int pageNo) {
        Map<String, Object> map = new HashMap<>(5);
        if (warehouseId != null) {
            map.put("warehouseId", warehouseId);
            map.put("queryString", queryString.toUpperCase());
            PageTbl page = this.getPage();
            page.setPageno(pageNo);
            page.setPagesize(pageSize);
            PageUtils utils = allocationService.selectUnbindShelf(page, map);
            page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
            //初始化分页对象
            executePageMap(map, page);
            map.put("result", utils.getList());
            map.put("total", utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        }else{
            map.put("result", "");
            map.put("total", 0);
        }
        return map;
    }

    /**
     * 功能描述:入库确认
     * @param allocationDetail 调拨单明细信息
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/confirmInstorage")
    @ResponseBody
    public Map<String, Object> confirmInstorage(AllocationDetail allocationDetail) {
        Map<String, Object> map = new HashMap<>(2);
        Integer state = allocationDetailService.selectById(allocationDetail.getId()).getState();
        if (state.equals(EmumConstant.locationChangeStatus.COMPLETE_CHANGE_IN.getCode())){
            map.put("result", false);
            map.put("msg", "入库完成,请勿重复提交！");
        } else {
            map = allocationService.confirmInstorage(allocationDetail.getId(), allocationDetail.getShelfId(), getUserId());
        }

        return map;
    }

    /**
     * 导出Excel
     * @param request
     * @param response
     */
    @RequestMapping(value = "/materialExcel", method = RequestMethod.POST)
    @ResponseBody
    public void materialExcel(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = new HashMap<>(6);
        map.put("ids", StringUtils.stringToInt(request.getParameter("ids")));
        map.put("qaCode", request.getParameter("queryQacode"));
        map.put("startTime", request.getParameter("queryStartTime"));
        map.put("endTime", request.getParameter("queryEndTime"));
        map.put("outShelfCode", request.getParameter("queryOutShelfCode"));
        map.put("inShelfCode", request.getParameter("queryInShelfCode"));
        try {
            String sheetName = "移库调拨清单" + "(" + DateUtils.getDay() + ")";
            response.setHeader("Content-Type", "application/force-download");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                    "ISO8859-1") + ".xls");

            Map<String, String> mapFields = new LinkedHashMap<>();
            String [] excelIndexArray = request.getParameter("queryExportExcelIndex").split(",");

            if (excelIndexArray.length==1&&"".equals(excelIndexArray[0])) {
                mapFields.put("qaCode", "质保单号");
                mapFields.put("batchNo", "批次号");
                mapFields.put("allCode", "单据号");
                mapFields.put("inStorageTimeStr", "入库时间");
                mapFields.put("factoryName", "调出厂区");
                mapFields.put("outWarehouseName", "调出仓库");
                mapFields.put("outShelfCode", "移出库位");
                mapFields.put("inFactoryName", "调入厂区");
                mapFields.put("inWarehouseName", "调入仓库");
                mapFields.put("inShelfCode", "移入库位");
                mapFields.put("outStorageName", "出库人");
                mapFields.put("pickManName", "入库人");
                mapFields.put("stateStr", "状态");
            }else {
                for (String s : excelIndexArray) {
                    if ("2".equals(s)) {
                        mapFields.put("qaCode", "质保单号");
                    } else if ("3".equals(s)) {
                        mapFields.put("batchNo", "批次号");
                    } else if ("4".equals(s)) {
                        mapFields.put("allCode", "单据号");
                    } else if ("5".equals(s)) {
                        mapFields.put("inStorageTimeStr", "入库时间");
                    } else if ("6".equals(s)) {
                        mapFields.put("factoryName", "调出厂区");
                    } else if ("7".equals(s)) {
                        mapFields.put("outWarehouseName", "调出仓库");
                    } else if ("8".equals(s)) {
                        mapFields.put("outShelfCode", "调出库位");
                    } else if ("9".equals(s)) {
                        mapFields.put("inFactoryName", "调入厂区");
                    } else if ("10".equals(s)) {
                        mapFields.put("inWarehouseName", "调入仓库");
                    } else if ("11".equals(s)) {
                        mapFields.put("inShelfCode", "调入库位");
                    } else if ("12".equals(s)) {
                        mapFields.put("outStorageName", "出库人");
                    } else if ("13".equals(s)) {
                        mapFields.put("pickManName", "入库人");
                    } else if ("14".equals(s)) {
                        mapFields.put("stateStr", "状态");
                    }
                }
            }

            DeriveExcel.exportExcel(sheetName, allocationService.getAlloInExcelList(map), mapFields, response, "");
            logService.logInsert("调拨入库数据导出", LogActionConstant.USER_EXPORT, request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
